<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>谈谈 AngularJS 到 Angular | 被删的前端游乐场</title>
    <meta name="description" content="Just playing around">
    
    
    <link rel="preload" href="/front-end-playground/assets/css/0.styles.a683ed26.css" as="style"><link rel="preload" href="/front-end-playground/assets/js/app.e5cf4092.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/3.c853767c.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/2.eed49fdd.js" as="script"><link rel="preload" href="/front-end-playground/assets/js/47.b5b053ce.js" as="script">
    <link rel="stylesheet" href="/front-end-playground/assets/css/0.styles.a683ed26.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/front-end-playground/" class="home-link router-link-active"><!----> <span class="site-name">被删的前端游乐场</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/front-end-playground/" class="nav-link">概述</a></div><div class="nav-item"><a href="/front-end-playground/front-end-basic/" class="nav-link">前端基础</a></div><div class="nav-item"><a href="/front-end-playground/vue/" class="nav-link">Vue学习</a></div><div class="nav-item"><a href="/front-end-playground/wxapp/" class="nav-link">小程序学习</a></div><div class="nav-item"><a href="/front-end-playground/front-end-others/" class="nav-link router-link-active">百家齐放</a></div><div class="nav-item"><a href="/front-end-playground/front-end-addon/" class="nav-link">前端的进击</a></div><div class="nav-item"><a href="/front-end-playground/faq.html" class="nav-link">FAQ</a></div> <a href="https://github.com/godbasin/front-end-playground" target="_blank" rel="noopener noreferrer" class="repo-link">
    Github
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/front-end-playground/" class="nav-link">概述</a></div><div class="nav-item"><a href="/front-end-playground/front-end-basic/" class="nav-link">前端基础</a></div><div class="nav-item"><a href="/front-end-playground/vue/" class="nav-link">Vue学习</a></div><div class="nav-item"><a href="/front-end-playground/wxapp/" class="nav-link">小程序学习</a></div><div class="nav-item"><a href="/front-end-playground/front-end-others/" class="nav-link router-link-active">百家齐放</a></div><div class="nav-item"><a href="/front-end-playground/front-end-addon/" class="nav-link">前端的进击</a></div><div class="nav-item"><a href="/front-end-playground/faq.html" class="nav-link">FAQ</a></div> <a href="https://github.com/godbasin/front-end-playground" target="_blank" rel="noopener noreferrer" class="repo-link">
    Github
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0" style="padding-top:10px;"><div class="kitty-main" data-v-0cd75e06><span class="stand" data-v-0cd75e06></span> <div class="cat" data-v-0cd75e06><div class="body" data-v-0cd75e06></div> <div class="head" data-v-0cd75e06><div class="ear" data-v-0cd75e06></div> <div class="ear" data-v-0cd75e06></div></div> <div class="face" data-v-0cd75e06><div class="nose" data-v-0cd75e06></div> <div class="whisker-container" data-v-0cd75e06><div class="whisker" data-v-0cd75e06></div> <div class="whisker" data-v-0cd75e06></div></div> <div class="whisker-container" data-v-0cd75e06><div class="whisker" data-v-0cd75e06></div> <div class="whisker" data-v-0cd75e06></div></div></div> <div class="tail-container" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06><div class="tail" data-v-0cd75e06></div></div></div></div></div></div></div></div></div></div> <p class="sidebar-heading open"><span>玩转 Angular</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/front-end-playground/front-end-others/angular-free/0-about-angular-from-1-to-4.html" class="active sidebar-link">谈谈 AngularJS 到 Angular</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/angular-free/0-about-angular-from-1-to-4.html#与-angularjs-共事" class="sidebar-link">与 AngularJS 共事</a></li><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/angular-free/0-about-angular-from-1-to-4.html#谈谈-angular" class="sidebar-link">谈谈 Angular</a></li><li class="sidebar-sub-header"><a href="/front-end-playground/front-end-others/angular-free/0-about-angular-from-1-to-4.html#结束语" class="sidebar-link">结束语</a></li></ul></li><li><a href="/front-end-playground/front-end-others/angular-free/0-di-in-angular.html" class="sidebar-link">谈谈 Angular 的依赖注入</a></li><li><a href="/front-end-playground/front-end-others/angular-free/1-init-angular-app-with-webpack.html" class="sidebar-link">1. 用 Webpack 启动 Angular 应用</a></li><li><a href="/front-end-playground/front-end-others/angular-free/2-inprove-app-configuration.html" class="sidebar-link">2. 改善应用配置</a></li><li><a href="/front-end-playground/front-end-others/angular-free/3-init-routes-and-assets.html" class="sidebar-link">3. 启用路由和添加静态资源</a></li><li><a href="/front-end-playground/front-end-others/angular-free/4-create-sidebar.html" class="sidebar-link">4. 制作左侧自动定位菜单</a></li><li><a href="/front-end-playground/front-end-others/angular-free/5-custom-input-component.html" class="sidebar-link">5. 自定义 input 表单控件</a></li><li><a href="/front-end-playground/front-end-others/angular-free/6-two-form-building.html" class="sidebar-link">6. 模型驱动和模板驱动的表单</a></li><li><a href="/front-end-playground/front-end-others/angular-free/7-dynamic-form.html" class="sidebar-link">7. 创建动态表单</a></li><li><a href="/front-end-playground/front-end-others/angular-free/8-radio-and-checkbox.html" class="sidebar-link">8. 表单的 radio 和 checkbox</a></li><li><a href="/front-end-playground/front-end-others/angular-free/9-upload-iamge.html" class="sidebar-link">9. 图片上传控件</a></li><li><a href="/front-end-playground/front-end-others/angular-free/10-add-conditions.html" class="sidebar-link">10. 向表单添加条件控制</a></li><li><a href="/front-end-playground/front-end-others/angular-free/11-option-dialog.html" class="sidebar-link">11. 使用动态表单制作选项配置对话框</a></li><li><a href="/front-end-playground/front-end-others/angular-free/12-config-and-create-form.html" class="sidebar-link">12. 配置以及生成表单</a></li><li><a href="/front-end-playground/front-end-others/angular-free/13-dynamic-list.html" class="sidebar-link">13. 动态列表配置</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>试试 Cycle.js</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>D3.js 和 Tree</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>试试 Three.js</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0" style="padding-top:;"><!----> <p class="sidebar-heading"><span>BOX2D.js 文档与教程</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><p>本文跟随着 Angular 的变迁聊聊这个框架，分享一些个人的理解。</p> <p>本骚年刚好是在之前的项目中使用到 Angular1，然后现在项目中负责将 Angular-beta 升级到 Angular-release 版本。与 Angular 结识较深，或许也是缘分吧。</p> <h2 id="与-angularjs-共事"><a href="#与-angularjs-共事" aria-hidden="true" class="header-anchor">#</a> 与 AngularJS 共事</h2> <h3 id="初始"><a href="#初始" aria-hidden="true" class="header-anchor">#</a> 初始</h3> <p>算了算，或许本骚年大概是两年前开始认识 AngularJS，那会 backbone.js、underscore.js 也还是刚开始流行，而热门的当然还是 jQuery、zepto 那些吧。
不得不说，当你去仔细理解 jQuery 的整个设计和架构的时候，才会知道里面的精华和美妙之处。而对 jQuery 的熟悉也使得我养成了从 dom 出发的编程思维。</p> <p>而 AngularJS 的出现，则颠覆了大多数 jQueryer 的思维方式。是的，我们需要从数据和状态开始思考组件，而不是随意地调动 dom 做想做的事情了。
什么<code>依赖注入（DI）</code>、<code>控制器（Controller）</code>、<code>指令（Directive）</code>、<code>服务（Service）</code>，<code>Scope</code>又是什么，为什么还有<code>digest()</code>和<code>apply()</code>。</p> <p>很多完全没接触过听说过的概念一拥而入，我没写过 JAVA，工程化又是什么？
当时的我，并不知道这些 MVC/MVVM 框架将对前端产生怎样的一个影响，或者说是带来哥怎样的未来。</p> <p>然而，就像我开始接触 javascript 一样，非科班的我没学过其他的语言，所以也不懂得为什么很多人诟病它。
AngularJS 的出现也是一样，从我和它们的初始开始它们就是以这样的形态存在，带来方便的同时也免不了有自己的小缺点，没有对错，没有好坏，只有优势或是不适合的一些场景。</p> <h3 id="并肩作战"><a href="#并肩作战" aria-hidden="true" class="header-anchor">#</a> 并肩作战</h3> <p>在一遍又一遍去理解 AngularJS 中的各种新概念和思维，以及一些业余的尝试之后，我开始把它选为队友，一起战斗。</p> <p>那时候其实 React 已经热门起来了，而 Vue 还没稳定。基于函数式编程的 React 受到很多人的追捧，而我因为还没去了解熟悉，光从社区和论坛的讨论中无法分辨好坏。</p> <p>直到产品经理问我，为什么 AngularJS 不行呢？
是啊，为什么不行呢？于是乎我把项目从 jQuery 迁移到 AngularJS 上了，准确来说，重构了。</p> <p>坑是不少，但是越到后面才越发现这次重构的正确性。项目的维护和拓展性能大幅度提升了，于是进入了业务模块快速开拓的阶段。</p> <p>其实我一直认为，作为一个业务产品，除了性能上的瓶颈，基本上没有框架好坏之分，只有设计架构的人能否正确理解业务和进行抽象架构。</p> <h3 id="框架纷争"><a href="#框架纷争" aria-hidden="true" class="header-anchor">#</a> 框架纷争</h3> <p>AngularJS 的工程化，一直到现在都会比 React/Vue 等框架更适合大规模业务的管理吧。尤其是像 PC 端的管理系统，围绕着简单的增删查改，需要的只是快速拓展业务，而很少复杂的需求和设计。
听过一句话，好的语言设计，能让刚接触的人写出的代码，和牛逼的人写出的代码几乎一样。</p> <p>函数式编程也好，面向对象也好，其实方式并不是那么重要，我们的最终目标一致的话，其实剩下的更多是相互之间磨合、配合然后高效前进。
React 很棒，它的虚拟 DOM 提升了性能，函数式编程让我们不需要再针对对象设计，我们可以畅快地抽象成一块块功能，然后一层层地封装或者调用。状态这种本不应该维护在函数式编程里面的东西，就让 Redux/Flux 等抽离出来进行管理吧。
Vue 也很不错，它相比 React 对前端人员友好和易上手，性能也紧跟 React，相比 AngularJS 要轻量、性能要好。尤其随着移动端的应用场景越来越大，单薄的 H5 页面很是适合吧。</p> <p>看看 AngularJS，概念太多上手难，框架太笨重不够灵活，甚至每次的升级都不做向下兼容（AngularJS、Angular-beta、Angular-release）。
然后我们对 Angular 的认识停留在这些一般般的风评中，忘记了它的工程化场景更适合大量业务模块的管理，也忽视了它的自我颠覆同时带来了一些很棒的特性（<code>Rxjs</code>和模块化），也不曾注意到现在的它更轻量、更灵活了。</p> <p>又或者是原 AngularJS 的使用者，看着 Angular 的断崖式升级以及 beta 时期也在不断跳级，望而止步，也没机会深入探视，然后发现灵魂还在，光芒耀眼。</p> <p>其实框架很多很杂，无法分辨不敢恭维又怎样。每个曾处于浪尖的新事物，必然有它的过人之处，多去了解学习，然后把精髓和优秀的思维带走，把不足记下以防踩坑。
若不去认识认识，怎么会知道这些框架的相似（路由、HTTP、生命周期、模板引擎等）。同样是服务的设计，依赖注入新的服务实例，而使用状态的抽离管理或许需要自行重置状态。</p> <h3 id="打怪升级"><a href="#打怪升级" aria-hidden="true" class="header-anchor">#</a> 打怪升级</h3> <p>ES6 和 Webpack 的出现，使得很多在 AngularJS 中的设计变得冗余或者稍微落后了。新式特性和语法糖，模块化在 Webpack 配合 Babel 的强助攻下破浪而出。
然后 Angular 推翻重来，出现了 Angular-beta 版本。当初宣言不进行 AngularJS 版本的兼容使得它吃了不少亏，毕竟后面还是出了迁移方案的。</p> <p>我们的项目从 AngularJS 1.2 升级到 1.5+，然后随着浪潮甩掉 Grunt 和 Gulp，调整上了 Webpack，同时 AngularJS1.5+的版本已经部分引入了 Angular 的一些新的思维（模块化），以及可以尽情使用 ES6/ES7 的新特性了。
不得不说，像 Promise、Module、Class 这些 API 的出现，真的是改变了很多的写码方式和效率。</p> <p>然后因为项目业务的不断拓展，以及维护人员的增加，团队到后面一致赞同 Typescript 的引入。事实证明约束的同时也省去了一些不必要的交流，代码的维护性变强了。
这个时候我们的项目状态是，<code>AngularJS 1.5</code> + <code>Webpack</code> + <code>Typescript</code>，同时因为联调的排期问题我们使用了 Angular 的 mock，真的很实用。</p> <h3 id="你好-angular"><a href="#你好-angular" aria-hidden="true" class="header-anchor">#</a> 你好 Angular</h3> <p>现在的项目也是相似的，PC 端的管理系统。当然它已经换了新马甲，虽然还是 beta 版本，不过很开心地说：你好呀，Angular。</p> <p>控制器（Controller）变成了组件（Component），然后定义都变成了装饰器（@decoretor from es7/typescript）。工厂（factory）没了，服务也要声明可注入（@injectavle）。
然后依赖注入的方式变了，beta 版的每次使用分类注入（分 directives/providers/pipe 注入），然后 release 版本的模块注入（NgModule 的 decleration/imports/exports/providers）。
事件绑定（<code>(click)</code>）和属性绑定（<code>[ngClass]</code>）的方式变了，定义某类组件都使用了 Class，我们看到了 this，作用域 Scope 被藏了起来。</p> <p>Angular 的 beta 到 release 版本也出现了一些大的变动，导致当初的版本已经找不到对应的文档和 API 了，遇到问题只能翻源码的效率太低了，于是我们升级到 release 的 4.0 版本。</p> <p>Angular-beta 到 release 也有不少的调整吧，具体大家可以参考<a href="https://godbasin.github.io/2017/05/21/angular2-beta-to-release/" target="_blank" rel="noopener noreferrer">《从 Angular-beta 到 Angular4-release 框架升级总结》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。</p> <p>项目里面也有些调整，上了 Angular-cli，它的内核也是 webpack。虽然不是很灵活，但在没有很多时间自己实践的情况下还是个不错的选择。然后有了 lazyload，有了公用组件模块 SharedModule。
团队的小伙伴也说过这么一句话，Angular 的项目，基本上拿过来复制粘贴就可以快速相应需求了。</p> <p>我们的工作很多时候最终目标是一个很棒的产品，无论是体验还是对用户友好。当然免不了地，对自己有些要求的我们也想要一个看起来漂亮的代码和项目架构。
而我个人的习惯一般是，在产品刚启动的时候快速开发，然后规模大了，进行抽象、规范、架构调整，以及多人配合时如何提高开发效率，减少开发和维护成本。</p> <p>很多人说，你要考虑以后的拓展性，要设计得完美。只是很多时候我们的产品总不能按照想象的顺利发展，我能做的，是和目前项目状况最适合的设计和架构，不多也不少。</p> <h2 id="谈谈-angular"><a href="#谈谈-angular" aria-hidden="true" class="header-anchor">#</a> 谈谈 Angular</h2> <h3 id="依赖注入"><a href="#依赖注入" aria-hidden="true" class="header-anchor">#</a> 依赖注入</h3> <p>Angular 的依赖注入可谓是灵魂了，之前有篇详细讲这个的文章<a href="https://godbasin.github.io/2017/05/28/di-in-angular/" target="_blank" rel="noopener noreferrer">《谈谈 Angular 中的依赖注入》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>，这里大致摘录一些。</p> <p>依赖注入在项目中，体现为项目提供了这样一个注入机制，有人负责提供服务，有人负责消耗服务，而这样的机制提供了中间的接口，并替使用者进行了创建并初始化这样的处理。
我们只需要知道，拿到的是完整可用的服务就好了，至于这个服务内部的实现，甚至是它又依赖了怎样的其他服务，都不需要关注。</p> <p>其实像我们设计一个项目，自行封装的一些组件和服务，然后再对它们的新建和初始化等等，也经常需要用到依赖注入这种设计方式的。
我们的服务也可以分为有记忆的和无记忆的，关键在于抽象完的组件是否内部记录自身状态，以及怎样维护这个状态等等，甚至设计不合理的话，这样的状态管理会经常使我们感到困扰，所以 Redux、Flux 和 Mobx 这样的状态管理框架也就出现了。</p> <p>而 Angular 在某种程度上替我们做了这样的工作，并提供我们使用。
在 Angular 里面我们常常通过服务来共享一些状态的，而这些管理状态和数据的服务，便是通过依赖注入的方式进行处理的。
依赖注入还有有个很棒的地方，就是单元测试很方便，测试的时候也注入需要的服务就好了。</p> <h3 id="模块化组织"><a href="#模块化组织" aria-hidden="true" class="header-anchor">#</a> 模块化组织</h3> <p>Angular 模块把组件、指令和管道打包成内聚的功能块，每个模块聚焦于一个特性区域、业务领域、工作流或通用工具。
我们不再只是将组件和功能进行模块抽象，也不只是再将一些组件和功能进行再封装，我们还要把这样的功能模块一步步放射到整个应用程序。</p> <p>这样的模块化思想层层包裹，我们的结构组织也层层地抽象封装，树结构的设计思想从模块组织到依赖注入延伸。
同时，依赖注入使得每个模块，不管层次薄的厚的，都能方便简单地进行状态管理。</p> <p>Angular 也提供了封装好的一些功能模块，像表单模块<code>FormModule</code>、路由模块<code>RouterModule</code>、Http 模块等等。</p> <h3 id="数据绑定"><a href="#数据绑定" aria-hidden="true" class="header-anchor">#</a> 数据绑定</h3> <p>我们都知道，在 Angular 中是使用双向绑定的，当然 Angular 中调整了分为事件绑定和属性绑定。
这在很多时候都解决了不少的问题，增删查过或者父子通讯最爱用了，换成 React/Vue 还得手动<code>setState()</code>之类的更新或者通过状态管理工具触发更新。</p> <p>说脏检查性能太糟，在 Angular1 中，当数据状态多了一次变更可能导致多次的联动脏检查计算，想想也是挺累的。
脏检查无非是，保存旧的数据，然后和新的数据比较计算，接着更新后再计算，直到没有新的变化为止。</p> <p>虽然有了很多像 React 的虚拟 DOM，以及 Vue 的数据跟踪 getter 和 setter，但在 Angular 中依然使用脏检查。
不一样的是，添加了 zone.js 对异步任务进行跟踪，把这个计算放进 worker，完了更新回主线程，是个类似多线程的设计，也提升了性能。</p> <p>在 Angular 中应用的组织类似 DOM，也是树结构的，脏检查会从根组件开始，自上而下对树上的所有子组件进行检查。
相比 Angular1 中的带有环的结构，这样的单向数据流效率更高，而且容易预测。</p> <h3 id="路由和-lazyload"><a href="#路由和-lazyload" aria-hidden="true" class="header-anchor">#</a> 路由和 lazyload</h3> <p>路由在 Angular-release 版本中设计成单独的功能模块，不再跟组件 Component 有密切的关系。</p> <p>我没有仔细研究过其他框架的路由模块，不过像 lazyload 这样的设计也肯定已经考虑进去了吧。
既然这样的话，那这里我拿 Angular 来说明一下 lazyload 的闪光之处。</p> <p>像我们打包页面，很多时候最终生成了一个<code>bundle.js</code>文件。这样，每次当我们请求页面的时候，都请求整个<code>bundle.js</code>并加载，有了 Webpack 或许我们只需要加载其中的某些模块，但还是需要请求到所有的代码。
很多时候我们或许不需要进入所有的模块，这个时候浪费了很多的资源，同时首屏体验也受到了影响。</p> <p>通过路由的 lazyload 以及上面提到的模块化，我们可以把每个 lazyload 的模块单独打包成一个<code>chunk</code>文件，当进入模块时才请求和加载，当我们的业务规模很大的时候，首屏速度得到大幅度提升。
使用 Angular-cli 可以很方便地进行路由的 lazyload，而若自行使用 webpack 构建，也只需要加上一个<code>angular-router-loader</code>就好了。</p> <h3 id="编程方式"><a href="#编程方式" aria-hidden="true" class="header-anchor">#</a> 编程方式</h3> <p>Angular 相对 Angular1 来说，编程方式改变太多。但是如果你熟悉 ES6/ES7，就发现 Angular 中的很多编程方式都很熟悉。
其实 Angular 看起来和 Angular1 完全是两个框架，很多时候是编程思维习惯导致的。就像当初使用 jQuery 的我们去学习 Angular 的感觉，但其实像 ES6/ES7 的出现这是一个必然的趋势吧。</p> <p>Typescript 的优势也体现在项目的维护性、代码的可读性以及多人配合的沟通效率。它也只是一种方案选择，当然如果有约定好的规范也是很不错的，最终还是看团队的意愿了。
Promise 的设计也让代码变得清晰连贯，数据状态的响应处理，同时我们可以方便地进行流式处理和异常处理。
Rxjs 的引入可以方便实现事件订阅，有时候可以配合 Websocket 来进行应用的部分推送更新等功能。
Class 的定义方式，配合装饰器 Decoretor，可以方便地统一的组件/服务/模块等的创建。</p> <h3 id="用-aot-进行编译"><a href="#用-aot-进行编译" aria-hidden="true" class="header-anchor">#</a> 用 AOT 进行编译</h3> <p>JIT 编译导致运行期间的性能损耗。由于需要在浏览器中执行这个编译过程，视图需要花更长时间才能渲染出来。
由于应用包含了 Angular 编译器以及大量实际上并不需要的库代码，所以文件体积也会更大。更大的应用需要更长的时间进行传输，加载也更慢。
预编译（AOT）会在构建时编译，这样可以在早期截获模板错误，提高应用性能。</p> <p>事实上只有一个 Angular 编译器，AOT 和 JIT 之间的差别仅仅在于编译的时机和所用的工具。
使用 AOT，编译器仅仅使用一组库在构建期间运行一次；使用 JIT，编译器在每个用户的每次运行期间都要用不同的库运行一次。</p> <p>AOT 使得页面渲染更快，无需等待应用首次编译，以及减少体积，提早检测模板错误等等。</p> <h3 id="拥抱变化，迎接未来"><a href="#拥抱变化，迎接未来" aria-hidden="true" class="header-anchor">#</a> 拥抱变化，迎接未来</h3> <p>身为框架，Angular 和 React、Vue 各有各的优劣，哪个更适合则跟产品设计、应用场景以及团队等各种因素密切相关，没有谁是最好的，只有当前最适合的一个。
Angular 的经常性不兼容，以及 1 到 2 的断崖式升级，或许对开发者不大友好。但其实，我很喜欢它的这些改变，干脆利落，自身的缺点由自己去克服。</p> <p>我们也何尝不是，为何要死守某个框架、某种语言，或是争好坏、分高下。
何尝不抱着开放的心态，拥抱变化，然后迎接未来呢？</p> <h3 id="参考"><a href="#参考" aria-hidden="true" class="header-anchor">#</a> 参考</h3> <ul><li><a href="https://github.com/xufei/blog/issues/25" target="_blank" rel="noopener noreferrer">《Angular 的变革》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="http://www.waitig.com/angular2-%E8%84%8F%E6%A3%80%E6%9F%A5%E8%BF%87%E7%A8%8B.html" target="_blank" rel="noopener noreferrer">《Angular 脏检查过程》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://zhuanlan.zhihu.com/p/20531896" target="_blank" rel="noopener noreferrer">《不要把 Rx 用成 Promise》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://angular.cn/docs/ts/latest/cookbook/aot-compiler.html" target="_blank" rel="noopener noreferrer">《预 (AoT) 编译器》<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h2 id="结束语"><a href="#结束语" aria-hidden="true" class="header-anchor">#</a> 结束语</h2> <p>以上只是本人的个人理解，或许存在偏差。世上本就没有十全十美的事物，大家都在努力地相互宽容和理解。<br>
那些我们想要分享的东西，肯定是存在很棒的亮点。而我们要做的，是尽力把自己看到的那完美的一面呈现给大家。</p></div> <!----> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/godbasin/front-end-playground/edit/sourcecode/docs/front-end-others/angular-free/0-about-angular-from-1-to-4.md" target="_blank" rel="noopener noreferrer">帮阿猪改善此页面！</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <!----> <blockquote>部分文章中使用了一些网站的截图，如果涉及侵权，请告诉我删一下谢谢~</blockquote> <div style="margin-top:30px;"><div class="el-row" style="margin-left:-10px;margin-right:-10px;"><div class="el-col el-col-24 el-col-sm-0 el-col-md-2 el-col-lg-4" style="padding-left:10px;padding-right:10px;display:block;"><div style="width:1px;height:1px;"></div></div> <div class="el-col el-col-24 el-col-sm-24 el-col-md-18 el-col-lg-16" style="padding-left:10px;padding-right:10px;"><div class="el-card box-card is-always-shadow"><div class="el-card__header"><div class="clearfix"><span>温馨提示喵</span></div></div><div class="el-card__body"> <div class="el-row" style="margin-left:-10px;margin-right:-10px;"><div class="el-col el-col-24 el-col-xs-24 el-col-sm-12" style="padding-left:10px;padding-right:10px;"><div class="el-image"><div class="image-slot"><img src="https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/assets/img/loading.gif" style="width:100%;"></div><!----></div></div> <div class="el-col el-col-24 el-col-xs-24 el-col-sm-12" style="padding-left:10px;padding-right:10px;"><div class="copyright-text"><div>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</div> <div>出处：被删的前端游乐场</div> <div>作者：<a href="https://github.com/godbasin" target="_blank">被删</a></div></div></div></div></div></div></div></div></div></footer> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/front-end-playground/front-end-others/angular-free/0-di-in-angular.html">
          谈谈 Angular 的依赖注入
        </a>
        →
      </span></p></div>  <div class="gitalk-container theme-default-content"><div id="gitalk-container" class="content"></div></div></main> <div id="kitty-container"><span><div role="tooltip" id="el-popover-8875" aria-hidden="true" class="el-popover el-popper" style="width:undefinedpx;display:none;"><!----><img src="https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/2code2.jpg" class="image"> <div class="text">牡羊猪的猫粮罐</div> </div><div id="kitty" style="background:url(https://github-imglib-1255459943.cos.ap-chengdu.myqcloud.com/assets/img/kitty0.svg);"></div></span> <div class="el-dialog__wrapper" style="display:none;"><div role="dialog" aria-modal="true" aria-label="牡羊猪是这样渐渐胖成猪的喵（点击图片可以切换噢）" class="el-dialog" style="margin-top:15vh;"><div class="el-dialog__header"><span class="el-dialog__title">牡羊猪是这样渐渐胖成猪的喵（点击图片可以切换噢）</span><button type="button" aria-label="Close" class="el-dialog__headerbtn"><i class="el-dialog__close el-icon el-icon-close"></i></button></div><!----><!----></div></div></div></div><div class="global-ui"></div></div>
    <script src="/front-end-playground/assets/js/app.e5cf4092.js" defer></script><script src="/front-end-playground/assets/js/3.c853767c.js" defer></script><script src="/front-end-playground/assets/js/2.eed49fdd.js" defer></script><script src="/front-end-playground/assets/js/47.b5b053ce.js" defer></script>
  </body>
</html>
